/*
 * I/O ports for Flying Fox
 *
 * Pin     | Type           | Function / alternate function
 * --------+----------------+------------------------------------------------
 * PA0     | Timer input    | Receiver 4 - TIM5_CH1 (pullup) / AN3 - ADC123_IN0
 * PA1     | Digital output | Pressure sensor clock - TIM2_CH2
 * PA2     | USART output   | GPS serial TXD - USART2_TX
 * PA3     | USART input    | GPS serial RXD - USART2_RX (pullup)
 * PA4     | Digital output | microSD CD (default 0)
 * PA5     | Digital output | microSD CLK - SPI1_SCK
 * PA6     | Digital input  | microSD CMD - SPI1_MOSI
 * PA8     | Timer input    | Receiver 3 - TIM1_CH1 (pullup)
 * PA9     | Timer input    | Receiver 6 - TIM1_CH2 (pullup) / AUXSER_TXD - USART1_TX
 * PA10    | Timer input    | Receiver 5 - TIM1_CH3 (pullup) / AUXSER_RXD - USART1_RX
 * PA11    | USB data       | USB data
 * PA12    | USB data       | USB data 
 * PA13    | Digital input  | JTAG TMS (pullup)
 * PA14    | Digital input  | JTAG TCLK (pullup)
 * PA15    | Digital input  | JTAG TDI (pullup)
 * PB0     | Timer input    | Receiver 1 - TIM3_CH3 (pullup) / AN1 - ADC12_IN8
 * PB1     | Timer input    | Receiver 2 - TIM3_CH4 (pullup) / AN2 - ADC12_IN9
 * PB2     | Digital input  | BOOT1 - tied low
 * PB3     | Digital input  | JTAG TDO (pullup)
 * PB4     | Digital output | - / future RX 7 - TIM3_CH1
 * PB5     | Digital output | - / future RX 8 - TIM3_CH2
 * PB6     | Timer output   | Servo 1 - TIM4_CH1
 * PB7     | Timer output   | Servo 2 - TIM4_CH2
 * PB8     | Timer output   | Servo 3 - TIM4_CH3
 * PB9     | Timer output   | Servo 4 - TIM4_CH4
 * PB10    | Digital output | Pressure sensor I2C SCL - I2C2_SCL
 * PB11    | Digital I/O    | Pressure sensor I2C SDA - I2C2_SDA
 * PB12    | Digital input  | DIO PB12 (pullup) / SPI2_NSS
 * PB13    | USART input    | Radio serial CTS - USART3_CTS (pullup) / SPI2_SCK
 * PB14    | USART output   | Radio serial RTS - USART3_RTS / SPI2_MISO
 * PB15    | Digital input  | DIO PB15 (pullup) / SPI2_MOSI
 * PC0     | Analog input   | Leveler Z - ADC123_IN10
 * PC1     | Analog input   | Leveler Y - ADC123_IN11
 * PC2     | Analog input   | Leveler X - ADC123_IN12
 * PC3     | Analog input   | Battery voltage sense
 * PC4     | Digital input  | USB sense
 * PC5     | Digital input  | microSD card detect
 * PC6     | Timer output   | Servo 5 - TIM8_CH1
 * PC7     | Timer output   | Servo 6 - TIM8_CH2
 * PC8     | Timer output   | Servo 7 - TIM8_CH3
 * PC9     | Timer output   | Servo 8 - TIM8_CH4
 * PC10    | USART output   | Radio serial TXD - USART3_TX
 * PC11    | USART input    | Radio serial RXD - USART3_RX (pullup)
 * PC12    | Digital output | LED1 - default 1:off
 * PC13    | Digital output | LED2 - default 1:off
 * PC14    | Digital output | USB pullup (default 0:off)
 * PC15    | Digital output | Pressure sensor XCLR (default 0)
 * PD0     | Oscillator     | Crystal oscillator
 * PD1     | Oscillator     | Crystal oscillator
 * PD2     | Digital input  | Receiver 7 (pullup) - deprecated
 * --------+----------------+------------------------------------------------
 */


/* Standard includes. */
#include <stdlib.h>

/* OS includes. */
#include "stm32f10x.h"

/* Flying Fox includes */
#include "ffox.h"
#include "analogin.h"
#include "serial.h"
#include "servo.h"
//#include "i2c.h"
#include "hp03.h"
#include "receiver.h"
#include "navigate.h"
//#include "usb.h"
#include "sensor.h"
#include "dbgprintf.h"


/* Priorities for the demo application tasks. */
#define MAIN_TASK_PRIORITY      ( tskIDLE_PRIORITY + 3 )
#define SENSOR_TASK_PRIORITY    ( tskIDLE_PRIORITY + 4 )

/*
 * Configure the processor for use with the Atmel demo board.  Setup is minimal
 * as the low level init function (called from the startup asm file) takes care
 * of most things.
 */
static void SetupHardware( void );


/*
 * Starts all the other tasks, then starts the scheduler. 
 */
int main( void )
{
    /* set up the hardware */
    SetupHardware();
    
    /* start the sensor aquisition tasks */
    Sensor_StartTasks(SENSOR_TASK_PRIORITY);

    /* start the flight navigation software */
    Navigate_StartTasks(MAIN_TASK_PRIORITY);
    
    /* Start the scheduler */
    vTaskStartScheduler();

    /* We should never get here as control is now taken by the scheduler. */
    return 0;
}

/*-----------------------------------------------------------*/

/*
 * NAME:        RCC_Configuration
 * ACTION:      Configure the system clocks
 */
 
void RCC_Configuration(void)
{
    /* Setup the microcontroller system. Initialize the Embedded Flash Interface,  
     initialize the PLL and update the SystemFrequency variable. */
    SystemInit();
    
    /* PCLK1 = HCLK/4 */
    RCC_PCLK1Config(RCC_HCLK_Div4);
    
    /* GPIO clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_AFIO, ENABLE);
    
    /* Enable GPIO clock */
    RCC_APB2PeriphClockCmd(USARTy_GPIO_CLK | USARTz_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
    
}

static void SetupHardware( void )
{
    /* initialise the STM32 hardware */
    RCC_Configuration();

    /* configure serial ports */
//    Serial_Init();
    
    /* enable debugging output */
//    dbgprintf_Init();
    
    /* configure the microsecond timer */
//    Timer_Init();
    
    /* configure analog inputs */
//    AnalogIn_Init();
    
    /* configure servo outputs */
    Servo_Init();
    
    /* configure receiver inputs */
//    Receiver_Init();
    
    /* configure I2C */
//    I2C_Init();
    
    /* configure altitude sensor */
//    HP03_Init();
    
    /* configure USB */
//    USB_Init();
}


/*
 * NAME:        FFox_TaskCreate
 * ACTION:      Creates a task in the same way as FreeRTOS's xTaskCreate, 
 *              except it reports errors in the debug stream
 */
 
void FFox_TaskCreate(pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask)
{
    portBASE_TYPE errorCode;
    
    errorCode = xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask);
    if (errorCode != pdPASS)
    {
        dbgprintf("ERROR - couldn't create task '%s': error code %ld\r\n", pcName, errorCode);
    }
}


